home *** CD-ROM | disk | FTP | other *** search
-
- title Run a program from within another program
-
-
- name RUNPROG
-
-
- save macro p1,p2,p3,p4,p5,p6,p7,p8,p9
- irp y,<p1,p2,p3,p4,p5,p6,p7,p8,p9>
- ifnb <y>
- push y
- endif
- endm
- restore macro
- irp z,<p9,p8,p7,p6,p5,p4,p3,p2,p1>
- ifnb <z>
- pop z
- endif
- endm
- endm
- endm
-
-
- cseg segment byte public 'code'
-
-
- assume cs:cseg,ds:nothing
-
-
- public run_program
-
- comment `
-
- Routine to execute a program from within a program.
-
- Calling stack:
- <sp+00> -> dword pointer to ASCIZ file name
- <sp+04> -> dword pointer to command line to pass to the program.
- First byte of the string is assumed to be the length
- of the string, and string must be terminated by a 0dh
- (carriage return) character.
-
- Return:
- AX contains the return code of the program.
-
- `
- run_program proc near
-
-
- FCB1Body equ byte ptr [bp]
- FCB2Body equ byte ptr [bp+16]
- EnvSeg equ word ptr [bp+32]
- CmdLinePtrO equ word ptr [bp+34]
- CmdLinePtrS equ word ptr [bp+36]
- FCB1PtrO equ word ptr [bp+38]
- FCB1PtrS equ word ptr [bp+40]
- FCB2PtrO equ word ptr [bp+42]
- FCB2PtrS equ word ptr [bp+44]
- ProgramName equ dword ptr [bp+64]
- CommandLine equ dword ptr [bp+68]
- push bp ; Save incoming fp
- save bx,cx,dx,si,di,ds,es ; Save the world (except for return)
- mov cs:OldSS,ss ; Save the stack
- mov cs:OldSP,sp
- sub sp,46 ; Make room for temporaries
- mov bp,sp ; And get a pointer to them
- lea ax,FCB1Body ; Get pointer to first FCB
- mov FCB1PtrS,ss ; Put pointers to default FCBs on stack
- mov FCB1PtrO,ax
- mov FCB2PtrS,ss
- lea ax,FCB2Body
- mov FCB2PtrO,ax
- lds si,CommandLine ; Get pointer to command line
- mov CmdLinePtrO,si ; Put it on the stack
- mov CmdLinePtrS,ds
- push ss ; Get pointer to FCBs
- pop es
- lea di,FCB1Body
- mov ax,2901h ; Function to parse file name
- int 21h ; Get first default FCB
- lea di,FCB2Body ; Point to second FCB
- mov ax,2901h ; Function again
- int 21h ; Parse it
- mov ah,30h ; Get the DOS version
- int 21h
- cmp al,3 ; Is it 3.x?
- mov ax,5200h ; "Get PSP" function for 2.x (undoc)
- jne Not3x ; No, use different function
- add ah,10h ; "Get PSP" function for 3.x
- Not3x:
- int 21h ; Get our PSP segment
- mov ds,bx ; Get it where we can use it
- mov ax,ds:2ch ; Get OUR environment
- mov EnvSeg,ax ; Put it in parameter block
- push ss ; Get segment of parameter block
- pop es
- lea bx,EnvSeg ; Point to parameter block
- lds dx,ProgramName ; Get pointer to program name
- mov ax,4b00h ; EXEC function to execute program
- int 21h ; Call DOS to do it
- mov ss,cs:OldSS ; Get our old stack back. Note that
- mov sp,cs:OldSP ; this takes care of the temps, too.
- jc run_err ; If CF set, return that as error
- mov ax,4d00h ; Function to get termination code
- int 21h ; Get from DOS
- run_err:
- restore ; Get all the registers back
- pop bp ; Get old fp back
- ret 8 ; Return to caller
- ;
- ; Local storage for SS & SP. Since the only segment we can be sure of is CS,
- ; we have to break all the rules and keep it with the code.
- ;
- OldSS dw 0
- OldSP dw 0
-
- run_program endp
-
- cseg ends
-
- end
-